<template>
  <div
    @mouseenter="hovering = true"
    @mouseleave="hovering = false"
    style="width: 100%"
  >
    <el-tree-select
      v-model="formData[prop]"
      :data="treeData"
      :props="treeProps"
      :render-after-expand="false"
      :disabled="inputDisabled"
      :placeholder="placeholder"
      :default-expanded-keys="expandedData"
      :expand-on-click-node="true"
      @change="changeValue"
      filterable
      check-on-click-node
      style="width: 100%"
    />
  </div>
</template>

<script setup>
import { ref, watch, onMounted, inject, onUnmounted } from 'vue';
import { useDisabled } from 'element-plus';
import { getDictionary } from '@/utils/system';
import emitter from "@/utils/bus";
import tool from "@/utils/tool";

const emit = defineEmits(['change'])
const props = defineProps({
  prop: {
    type: String,
    default: ''
  },
  dictCode: {
    type: String,
    default: ''
  },
  showText: Boolean
});
const formData = inject('formData');
const placeholder = ref(props.placeholder);
const message = ref('');
const dictList = ref([]);
const expandedData = ref([]);
const inputDisabled = useDisabled();
const treeData = ref([]);
const treeProps = ref({
  children: 'children',
  isLeaf: 'leaf',
  label: 'text'
});
const hovering = ref(false);

const init = () => {
  message.value = '';
  treeData.value = [];
  loadDicAndShow(props.dictCode);

  emitter.off('dictionary.change');
  emitter.on('dictionary.change', () => {
    loadDicAndShow(props.dictCode);
  });
};

const loadDicAndShow = async(dictCode) => {
  dictList.value = await getDictionary(dictCode) || [];
  treeData.value = listToTree(tool.deepClone(dictList.value));
  expandedData.value = ['0'];
};

const changeValue = () => {
  emit('change');
};

const listToTree = (list) => {
  let map = {}, node, result = [], i;
  for (i = 0; i < list.length; i++) {
    node = list[i];
    node.pid = node.pid || '0';
    node.id = node.key;
    node.text = node.value;

    map[node.id] = i;
    node.children = [];
  }

  for (i = 0; i < list.length; i++) {
    node = list[i];
    if (node.pid && node.pid !== '0') {
      if (map[node.pid] >= 0) {
        list[map[node.pid]].children.push(node);
      }
    } else {
      result.push(node);
    }
  }

  return result;
};

watch(() => props.dictCode, () => {
  init();
}, {immediate: true});

onMounted(() => {
  emitter.off("dictionary.change", init);
  emitter.on("dictionary.change", init);
});

onUnmounted(() => {
  emitter.off("dictionary.change", init);
});
</script>